/**
 * test_mutex.c: Tests if the mutex implementations work correctly
 *
 * Correct output should be:
 *    0 Yay!
 *
 * Author: 	Nora Tarano <ntarano@andrew.cmu.edu>
 *          Yuan Meng <yuanm@andrew.cmu.edu>
 *          Yipeng Yun <yipengy@andrew.cmu.edu>
 * Date: 	Dec 11, 2011
 *
 */
 
#include <stdio.h>
#include <task.h>
#include <unistd.h>
#include <lock.h>

unsigned int x;
int mutex;

void panic(const char* str)
{
	puts(str);
	while(1);
}

void fun1(void* str __attribute__((unused)))
{
	while(1)
	{
		mutex_lock(mutex);
		x++;
		x--;
		mutex_unlock(mutex);
		event_wait(0);
	}
}

void fun2(void* str __attribute__((unused)))
{
	while(1)
	{
		mutex_lock(mutex);
		x -= 100;
		x += 100;
		mutex_unlock(mutex);
		event_wait(1);
	}
}

void fun3(void* str __attribute__((unused)))
{
	while (1)
	{
		mutex_lock(mutex);
		printf("%d", x);
		if (!x)
			printf(" Yay!\n");
		else
			printf(" Nooooooo!\n");
		mutex_unlock(mutex);
		event_wait(3);
	}
}

int main(int argc __attribute__((unused)), char** argv __attribute__((unused)))
{
	mutex = mutex_create();

	x = 0;

	task_t tasks[3];
	
	tasks[0].lambda = fun1;
	tasks[0].data = (void*)0;
	tasks[0].stack_pos = (void*)0xa2000000;
	tasks[0].C = 1;
	tasks[0].T = PERIOD_DEV0;
	tasks[0].B = 1;

	tasks[1].lambda = fun2;
	tasks[1].data = (void*)0;
	tasks[1].stack_pos = (void*)0xa1500000;
	tasks[1].C = 1;
	tasks[1].T = PERIOD_DEV1;
	tasks[1].B = 0;

	tasks[2].lambda = fun3;
	tasks[2].data = (void*)0;
	tasks[2].stack_pos = (void*)0xa1000000;
	tasks[2].C = 1;
	tasks[2].T = PERIOD_DEV3;
	tasks[2].B = 2;

	task_create(tasks, 3);
	
	return 0;
}
